#pragma region Include
#include <Windows.h>
#include <WindowsX.h>
#include <ShellAPI.h>
#include <conio.h>
#include <stdio.h>
#include <io.h>
#include <iostream>
#include <locale.h>

#include "net.h"
#include "parser.h"
#include "response.h"
#include "other.h"
#include "MIME-types.h"
#include "charset_codes.h"
#include "control.h"
#include "file.h"
#pragma endregion Include

#define WM_MSG_TRAY_ICON	5000

#define ROOT_DOCUMENT	"d:\\"

#define ID_EXIT		1000
HMENU hContextMenu = NULL;

CSrvCon srv;

HANDLE th = 0;
HANDLE th_creating = NULL;
HANDLE ev_created = NULL;

HANDLE th_srv = 0;
bool th_srv_close = false;

DWORD result = 0;

FILE *fp; 

CRITICAL_SECTION cs;

void CreateContextMenu();

void thread_routine(LPVOID params)
{
	CSrvCon *p_srv = (CSrvCon *)params;
	CControl *control;
	char *response = NULL;
	long response_size = 0;
	char buf[MAX_BUF];
	SOCKET clt_s = p_srv->get_clt_socket();

	control = new CControl;

	memset(buf, 0 , MAX_BUF);

	EnterCriticalSection(&cs);

	Sleep(200);
	p_srv->recv_data_from(clt_s, buf, MAX_BUF);

	LeaveCriticalSection(&cs);

	if(strlen(buf) == 0)
	{
		p_srv->shutdown_client(clt_s);

		delete control;

		SetEvent(ev_created);
		
		ExitThread(1);
	}

	response = control->get_response(buf);
	response_size = control->get_response_size();

	EnterCriticalSection(&cs);

	if(response)
	{
		p_srv->send_data_to(clt_s, response, response_size - 1);
	}

	delete control;

	p_srv->shutdown_client(clt_s);

	LeaveCriticalSection(&cs);

	SetEvent(ev_created);
	
	ExitThread(0);
}

void thread_srv(LPVOID params)
{
	while(1)
	{
		result = WaitForSingleObject(ev_created, INFINITE);
		
		srv.accept_connection();

		if(th_srv_close)
			break;

		if(result == WAIT_OBJECT_0)
		{
			ResetEvent(ev_created);

			th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_routine,
					(LPVOID)&srv, CREATE_SUSPENDED, NULL);
			if(th == NULL)
				break;

			ResumeThread(th);
		}
	}

	ExitThread(0);
}

LRESULT CALLBACK WndProc(HWND hwnd,
	UINT msg, 
	WPARAM wParam,
	LPARAM lParam)
{
	HDC hdc = NULL;
	PAINTSTRUCT ps;
	POINT pnt;

	switch(msg)
	{
	case WM_CREATE:
		srv.set_address("0.0.0.0");
		srv.open_port();

		ev_created = CreateEvent(NULL, true, true, "cr");

		InitializeCriticalSection(&cs);

		//timer_id = SetTimer(hwnd, NULL, 5000, NULL);
		th_srv = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_srv,
					NULL, 0, NULL);
		break;
	case WM_TIMER:
		
		break;
	case WM_CLOSE:
		//CloseHandle(thread_srv);
		EnterCriticalSection(&cs);
		th_srv_close = true;
		LeaveCriticalSection(&cs);

		Sleep(100);

		DeleteCriticalSection(&cs);
		srv.close_port();
		CloseHandle(ev_created);

		//KillTimer(hwnd, timer_id);

		DestroyWindow(hwnd);
		break;
	case WM_LBUTTONDOWN:
		MessageBox(NULL, "push", "WRC", MB_OK);
		break;
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);

		EndPaint(hwnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(1);
		break;
	case WM_MSG_TRAY_ICON:
		switch(LOWORD(lParam))
		{
		/*case WM_LBUTTONDOWN:
			if(!ShowWindow(hwnd, SW_HIDE))
				ShowWindow(hwnd, SW_SHOW);
			break;*/
		case WM_RBUTTONDOWN:
			GetCursorPos(&pnt);

			TrackPopupMenu(hContextMenu,
				0, pnt.x, pnt.y, 0, hwnd, NULL);

			break;
		}
		//MessageBox(NULL, "push", "WRC", MB_OK);
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case ID_EXIT:
			SendMessage(hwnd, WM_CLOSE, 0, 0);
			break;
		}
		break;
	}

	return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst,
	HINSTANCE hPrevInst,
	LPSTR lpCmdLine,
	int iShowCmd)
{
	//char * cur_loc = setlocale(LC_ALL, "");
	setlocale(LC_ALL, "Russian_Russia.1251");
	
	HICON hIcon = NULL;

	hIcon = (HICON)LoadImage(NULL, "wrc.ico",
		IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
	if(!hIcon)
	{
		MessageBox(NULL, "Not exist wrc.ico", "Where ico?", MB_OK|MB_ICONERROR);
		return 1;
	}

	WNDCLASS wc;

	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
	wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
	wc.hIcon = hIcon;
	wc.hInstance = hInst;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = "WRC class";
	wc.lpszMenuName = NULL;
	wc.style = 0;

	if(!RegisterClass(&wc))
	{
		MessageBox(NULL, "1", "1",MB_OK);
		return 1;
	}

	HWND hwnd = NULL;

	hwnd = CreateWindowEx(0, "WRC class", "WRC", 
		WS_OVERLAPPEDWINDOW, 0, 0, 300, 300,
		NULL, NULL, hInst, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "2", "2",MB_OK);
		return 2;
	}

	ShowWindow(hwnd, SW_HIDE);
	UpdateWindow(hwnd);

	if(hIcon == NULL)
	{
		MessageBox(NULL, "3", "3",MB_OK);
		DWORD result = GetLastError();
		return 3;
	}

	CreateContextMenu();

	NOTIFYICONDATA nid;

	nid.cbSize = sizeof(NOTIFYICONDATA);
	nid.hWnd = hwnd;
	nid.hIcon = hIcon;
	nid.uID = 100;
	nid.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
	strcpy(nid.szTip, "WRC");
	nid.uCallbackMessage = WM_MSG_TRAY_ICON;

	bool res = Shell_NotifyIcon(NIM_ADD, &nid);

	MSG msg;

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	Shell_NotifyIcon(NIM_DELETE, &nid);

	DestroyMenu(hContextMenu);
	DestroyIcon(hIcon);

	return msg.wParam;
}

void CreateContextMenu()
{
	hContextMenu = CreatePopupMenu();

	AppendMenu(hContextMenu, MF_STRING, ID_EXIT, "Exit");
}